#include <iostream>

#include "main_lib.h"
#include "Student.h"
#include "Student_lib.h"
#include "Lecturer.h"
#include "Lecturer_lib.h"
#include "Subject.h"
#include "Subject_lib.h"
#include "Course.h"
//#include "Course_lib.h"
#include "Registration.h"
#include "Registration_lib.h"
#include "Result.h"
#include "result_lib.h"
using namespace std;

int c1 = -1, c2 = 0, i, j, k, m, n, o, _key_id;
string _key;

Student _stu;
Lecturer _lec;
Subject _sub;
Course _cs;
Registration _re;
Result _rs;

Student stu[1000];
Student _stu_result[1000];
Lecturer lec[1000];
Lecturer _lec_result[1000];
Subject sub[1000];
Subject _sub_result[1000];
Course cs[1000];
Course _cs_result[1000];
Registration re[1000];
Registration _re_result[1000];
Result rs[1000];
Result _rs_result[1000];

int Main_menu_selector(){
	int temp_i;
	cout<<"                       *          *          *                   \n";
	cout<<"Main Menu: \n";
	cout<<"1. Manage Students\n";
	cout<<"2. Manage Lecturers\n";
	cout<<"3. Manage Subjects list\n";
	cout<<"4. Timetable, Course Registration\n";
	cout<<"5. Study Result\n";
	cout<<"Please choose function:";
	cin>>temp_i;
	system("cls");
	return temp_i;
}

int Student_menu_selector(){
	int temp_i;
	cout<<"                       *          *          *                   \n";
	cout<<"1. Manage Student\n";
	cout<<"\t1. Show all students\n";
	cout<<"\t2. Get student by id\n";
	cout<<"\t3. Get students by name\n";
	cout<<"\t0. Return previous\n"; 
	cout<<"Please choose function:";
	cin>>temp_i;
	system("cls");
	if(temp_i!=0){
	return temp_i+10;
	}
	else{
		return temp_i;
	}
}
int Lecturer_menu_selector(){
	int temp_i;
	cout<<"                       *          *          *                   \n";
	cout<<"2. Manage Lecturer\n";
	cout<<"\t1. Show all lecturers\n";
	cout<<"\t2. Get lecturer by id\n";
	cout<<"\t3. Get lecturers by name\n";
	cout<<"\t0. Return previous\n"; 
	cout<<"Please choose function:";
	cin>>temp_i;
	system("cls");if(temp_i!=0){
	return temp_i+20;
	}
	else{
		return temp_i;
	}
}
int Subject_menu_selector(){
	int temp_i;
	cout<<"                       *          *          *                   \n";
	cout<<"3. Manage Subjects list\n";
	cout<<"\t1. Show all subjects\n";
	cout<<"\t2. Get subject by id\n";
	cout<<"\t3. Get pre-subject by id\n";
	cout<<"\t0. Return previous\n"; 
	cout<<"Please choose function:";
	cin>>temp_i;
	system("cls");if(temp_i!=0){
	return temp_i+30;
	}
	else{
		return temp_i;
	}
}
int Reg_and_course_menu_selector(){
	int temp_i;
	cout<<"                       *          *          *                   \n";
	cout<<"4. Timetable, Course Registration\n";
	cout<<"\t1. Get overall timetable\n";
	cout<<"\t2. Get overall timetable\n";
	cout<<"\t3. Get timetable by student id\n";
	cout<<"\t4. Get timetable by lecturer id\n";
	cout<<"\t5. List students by courses\n";
	cout<<"\t6. Validate all courses\n";
	cout<<"\t7. Export students lists to files\n";
	cout<<"\t0. Return previous\n"; 
	cout<<"Please choose function:";
	cin>>temp_i;
	system("cls");if(temp_i!=0){
	return temp_i+40;
	}
	else{
		return temp_i;
	}
}
int Result_menu_selector(){
	int temp_i;
	cout<<"                       *          *          *                   \n";
	cout<<"5. Study Result\n";
	cout<<"\t1. Get results of student by id\n";
	cout<<"\t2. Get results by subject\n";
//	cout<<"18. Get results by course\n";
	cout<<"\t0. Return previous\n"; 
	cout<<"Please choose function:";
	cin>>temp_i;
	system("cls");if(temp_i!=0){
	return temp_i+50;
	}
	else{
		return temp_i;
	}
}
void Show_all_student(){
	i = 0;
	Read_student("Student.txt", stu, i);
	cout<<"ID             FULLNAME    ADDRESS         DOB YEAR MAJOR\n";
	for (j = 0; j < i; j++){
		stu[j].Show_student();
	}

	
}

void Show_student_by_id(){
	i = 0;
	Read_student("Student.txt", stu, i);

	cout<<"Specify student id=";
	cin>>_key_id;

	while (cin.fail()){
		cin.clear();
		cin.ignore(10000, '\n');
		cout<<"Specify student id=";
		cin >>_key_id;
	}

	_stu = Get_student_by_id(_key_id, stu, i);

	if (_stu.Get_id() != 0){
		_stu.Show_student();
	}else{
		cout<<"No student found!\n";
	}
}

int main()
{
    
	system("cls");
    while (c1!=0){
		
        if(c2==0){
			c1 = Main_menu_selector();
		}
		
        switch (c1){
		case 1:
			c2=Student_menu_selector();
			break;
		case 2:
			c2=Lecturer_menu_selector();
			break;
		case 3:
			c2=Subject_menu_selector();
			break;
		case 4:
			c2=Reg_and_course_menu_selector();
			break;
		case 5:
			c2=Result_menu_selector();
			break;
		}
		if(c2 != 0){
			switch(c2){
			case 11:
				Show_all_student();
				break;
			
			case 12:
				Show_student_by_id();
				break;

			case 13:
				i = 0;
				Read_student("Student.txt", stu, i);

				cout<<"Specify student name:";
				cin >>_key;

				j = 0;
				Get_students_by_name(_key, stu, i, _stu_result, j);

				if (j == 0){
					cout<<"No student found!\n";
				}else{
					for (k = 0; k < j; k++){
						_stu_result[k].Show_student();
					}
				}

				break;
			case 21:
				i = 0;
				Read_lecturer("Lecturer.txt", lec, i);

				for (j = 0; j < i; j++){
					lec[j].Show_lecturer();
				}

				break;

			case 22:
				i = 0;
				Read_lecturer("Lecturer.txt", lec, i);

				cout<<"Specify lecturer id=";
				cin>>_key_id;

				while (cin.fail()){
					cin.clear();
					cin.ignore(10000, '\n');
					cout<<"Specify lecturer id=";
					cin>>_key_id;
				}

				_lec = Get_lecturer_by_id(_key_id, lec, i);
				if (_lec.Get_id() != 0){
					_lec.Show_lecturer();
				}else{
					cout<<"No lecturer found!\n";
				}

				break;

			case 23:
				i = 0;
				Read_lecturer("Lecturer.txt", lec, i);

				cout<<"Specify lecturer name:";
				cin >>_key;

				j = 0;
				Get_lectures_by_name(_key, lec, i, _lec_result, j);

				if (j == 0){
					cout<<"No lecturer found!\n";
				}else{
					for (k = 0; k < j; k++){
						_lec_result[k].Show_lecturer();
					}
				}

				break;

			case 31:
				i = 0;
				Read_subject("Subject.txt", sub, i);

				for (j = 0; j < i; j++){
					sub[j].Show();
				}

				break;

			case 32:
				i = 0;
				Read_subject("Subject.txt", sub, i);

				cout<<"Specify subject id=";
				cin>>_key;

				_sub = Get_subject_by_id(_key, sub, i);
				if (_sub.Get_credit() != 0){
					_sub.Show();
				}else{
					cout<<"No subject found!\n";
				}

				break;

			case 33:
				i = 0;
				Read_subject("Subject.txt", sub, i);

				cout<<"Specify subject id=";
				cin>>_key;

				_sub = Get_subject_by_id(_key, sub, i);
				if (_sub.Get_credit() != 0){
					_sub = Get_presub_by_id(_sub, sub, i);

					if (_sub.Get_credit() != 0){
						_sub.Show();
					}else{
						cout<<"No pre-subject required!\n";
					}
				}else{
					cout<<"No subject found!\n";
				}

				break;

			case 41:
				i = 0;
				Read_course("Course.txt", cs, i);
				j = 0;
				Read_lecturer("Lecturer.txt", lec, j);
				k = 0;
				Read_subject("Subject.txt", sub, k);

				Print_timetable(cs, i, sub, k, lec, j);

				break;
			case 42:
				i = 0;
				Read_course("Course.txt", cs, i);
				j = 0;
				Read_lecturer("Lecturer.txt", lec, j);
				k = 0;
				Read_subject("Subject.txt", sub, k);
				
				cout<<"Specify semester = ";
				cin>>_key_id;
				cin.clear();

				while (cin.fail()){
					cin.clear();
					cin.ignore(10000, '\n');
					cout<<"Specify semester id = ";
					cin>>_key_id;
				}
				n = 0;
				Get_courses_by_semester(_key_id, cs, i, _cs_result, j);

				if (j != 0){
					Print_timetable(_cs_result, j, sub, k, lec, m);
				}else{
					cout<<"Student not found or no registration exist!\n";
				}
				break;
			case 43:
				i = 0;
				Read_registration("Registration.txt", re, i);
				j = 0;
				Read_lecturer("Lecturer.txt", lec, j);
				k = 0;
				Read_subject("Subject.txt", sub, k);
				
				cout<<"Specify student id=";
				cin>>_key_id;
				cin.clear();

				while (cin.fail()){
					cin.clear();
					cin.ignore(10000, '\n');
					cout<<"Specify student id=";
					cin>>_key_id;
				}

				n = 0;
				Get_courses_by_student(_key_id, re, i, _cs_result, j);

				if (n != 0){
					Print_timetable(_cs_result, j, sub, k, lec, j);
				}else{
					cout<<"Student not found or no registration exist!\n";
				}

				break;

			case 44:
				i = 0;
				Read_registration("Registration.txt", re, i);
				j = 0;
				Read_lecturer("Lecturer.txt", lec, j);
				k = 0;
				Read_subject("Subject.txt", sub, k);
				
				cout<<"Specify lecturer id=";
				cin>>_key_id;

				while (cin.fail()){
					cin.clear();
					cin.ignore(10000, '\n');
					cout<<"Specify lecturer id=";
					cin>>_key_id;
				}

				n = 0;
				Get_courses_by_lecturer(_key_id, re, i, _cs_result, n);
				if (n != 0){
					Print_timetable(_cs_result, n, sub, k, lec, j);
				}else{
					cout<<"Lecturer not found!\n";
				}

				break;

			case 45:
				i = 0;
				Read_registration("Registration.txt", re, i);

				j = 0;
				Read_subject("Subject.txt", sub, j);

				k = 0;
				Read_lecturer("Lecturer.txt", lec, k);

				cout<<"Specify subject id:";
				cin>>_key;

				cout<<"Specify lecturer id=";
				cin>>_key_id;

				while (cin.fail()){
					cin.clear();
					cin.ignore(10000, '\n');
					cout<<"Specify lecturer id=";
					cin>>_key_id;
				}

				m = 0;
				Get_students_by_course(_key, _key_id, re, i, _stu_result, m);
				system("cls");
				if (m != 0){
					ostringstream ss, ssf;

					_sub = Get_subject_by_id(_key, sub, j);
					_lec = Get_lecturer_by_id(_key_id, lec, k);

					ss << "Subject: " << _sub.Get_sname() << "\n" << "Lecturer: " << _lec.Get_fname() << "\n\n" << "ID\tFull name\n";
					string _temp = Get_students_list(_stu_result, m);
					ssf << ss.str() << _temp << "\nThis list contains " << m << " student(s)\n";
					cout<<ssf.str();
				}else{
					cout<<"Subject id or lecturer id not specified properly!\n";
				}

				break;

			case 46:
				i = 0;
				Read_registration("Registration.txt", re, i);

				j = 0;
				Read_subject("Subject.txt", sub, j);

				k = 0;
				Read_lecturer("Lecturer.txt", lec, k);

				for (m = 0; m < j; m++){
					for (n = 0; n < k; n++){
						_key = sub[m].Get_id();
						_key_id = lec[n].Get_id();
						Get_students_by_course(_key, _key_id, re, i, _stu_result, o);

						if (o > 0){
							if (o < 5){
								cout << "Course "<<sub[m].Get_sname()<<" of lecturer "<<lec[n].Get_fname()<<" has less than minimum 3 students! (Currently: "<<o<<")\n";
							}

							if (o > 101){
								cout << "Course "<<sub[m].Get_sname()<<" of lecturer "<<lec[n].Get_fname()<<" exceeds maximum 5 students! (Currently: "<<o<<")\n";
							}
						}
					}
				}

				break;

			case 47:
				i = 0;
				Read_registration("Registration.txt", re, i);

				j = 0;
				Read_subject("Subject.txt", sub, j);

				k = 0;
				Read_lecturer("Lecturer.txt", lec, k);

				for (m = 0; m < j; m++){
					for (n = 0; n < k; n++){
						_key = sub[m].Get_id();
						_key_id = lec[n].Get_id();
						Get_students_by_course(_key, _key_id, re, i, _stu_result, o);
						if (o > 0){
							ostringstream ss, ss2, ss3, ss4, ss5, ssf;
							ofstream file;

							ss << "students_lists\\" << _key <<"."<< _key_id <<".txt";
							file.open(ss.str().c_str());

							string _subject = "Subject: " + sub[m].Get_sname() + "\n";
							string _lecturer = "Lecturer: " + lec[n].Get_fname() + "\n";
							ss2 << "Midterm: " << sub[m].Get_percent_midterm() << "%\n\n";
							ss3 << setw(3) << "ID" << setw(25) << "Full name" << setw(15) << "Date of Birth" << setw(4) << "Year\n";
							ss4 << Get_students_list(_stu_result, o);
							ss5 << "\n---This list contains " << o << " student(s)---";

							ssf << _subject << _lecturer << ss2.str() << ss3.str() << ss4.str() << ss5.str();

							file << ssf.str();
							file.close();

							cout << _key << ":" << _key_id << "... DONE!\n";
						}
					}
				}

				break;

			case 51:
				i = 0;
				Read_result("Result.txt", rs, i);
				k = 0;
				Read_student("Student.txt", stu, k);
				m = 0;
				Read_subject("Subject.txt", sub, m);
				
				cout<<"Specify student id=";
				cin>>_key_id;

				while (cin.fail()){
					cin.clear();
					cin.ignore(10000, '\n');
					cout<<"Specify student id=";
					cin >>_key_id;
				}

				j = 0;
				Get_student_results(_key_id, rs, i, _rs_result, j);
				cout<< "Result for student " << Get_student_by_id(_key_id, stu, k).Get_fname() <<"\n";
				if (j != 0){
					cout<<setw(30)<<"Subject"<<setw(10)<<"Midterm"<<setw(10)<<"Final"<<setw(10)<<"Fail/Pass"<<"\n\n";
					for (k = 0; k < j; k++){
						Subject temp_s = Get_subject_by_id(_rs_result[k].Get_s_id(),sub,m);
						int _av = (_rs_result[k].Get_midterm() * temp_s.Get_percent_midterm() + _rs_result[k].Get_final() * (100 - temp_s.Get_percent_midterm()))/100;
						string _fp;

						if ((_av < 10) || (_rs_result[k].Get_final() <= 4)){
							_fp = "F";
						}else{
							_fp = "P";
						}
						//Show_result(_rs_result[k]);
						cout<<setw(30)<<temp_s.Get_sname()<<setw(10)<<_rs_result[k].Get_midterm()<<setw(10)<<_rs_result[k].Get_final()<<setw(10)<<_fp<<"\n";
					}
				}else{
					cout<<"No student found or no registration exists!\n";
				}

				break;

			case 52:
				i = 0;
				Read_result("Result.txt", rs, i);

				cout<<"Specify subject id=";
				cin>>_key;

				j = 0;
				Get_subject_results(_key, rs, i, _rs_result, j);

				if (j != 0){
					for (k = 0; k < j; k++){
						Show_result(_rs_result[k]);
					}
				}else{
					cout<<"No subject found or no registration exists!\n";
				}

				break; 
			}
        }
    
	}
    return 0;
}
